local LangAI = require "packages/lang/AI/LangAI"
local LU = require "packages/lang/LUltiity"
local HobbyGenPool = require "packages/lang/HobbyGenPool"
-------------------------------修改或新增Player类一些函数来适配人机------------------
--服务器玩家类修改
local ServerPlayer = require "server.serverplayer"
function ServerPlayer:initialize(_self)
  Player.initialize(self)
  self.serverplayer = _self -- 控制者
  self._splayer = _self -- 真正在玩的玩家
  self._observers = { _self } -- "旁观"中的玩家，然而不包括真正的旁观者
  self.id = _self:getId()
  self.room = nil
  self.request_data = ""
  self.client_reply = ""
  self.default_reply = ""
  self.reply_ready = false
  self.reply_cancel = false
  self.phases = {}
  self.skipped_phases = {}
  self.phase_state = {}

  self._fake_skills = {}
  self._manually_fake_skills = {}
  self.prelighted_skills = {}
  self._prelighted_skills = {}

  self._timewaste_count = 0
  self.ai = LangAI:new(self)
end
--卖血逻辑
function Player:canUseEquip(subtype)
  return not table.contains(self.sealedSlots,Util.convertSubtypeAndEquipSlot(subtype))
end
--卖血逻辑
function Player:canSubLogic()
  if self.hp / self.maxHp > 0.5 then return true end
  local exp = Exppattern:Parse("peach,analeptic")
  return #table.filter(self.player_cards[Player.Hand],function(cid) return exp:match(Fk:getCardById(cid)) end) > 0
end
-- local function canNoSubHp(player,from)
--   table.find(player.player_skills,function(s) return s.trueName == from)
-- end
function Player:canSubHp(usecardfrom,usecard)
  if not self.subhp or (usecardfrom.nosubhp and not LangAI:ISSAMECAMP(self,usecardfrom) and usecard and Exppattern:Parse(usecardfrom.nosubhp):match(usecard)) then return false end
  if self.subhp == 1 then
    return self:canSubLogic()
  elseif self.subhp == 2 then
    if self:getMark("isdamaged-turn") == 0 and self.hp / self.maxHp > 0.5 then
      return true
    end
  elseif self.subhp == 3 then
    if usecardfrom then
      if LangAI:ISSAMECAMP(self,usecardfrom) then
        return false
      else
        return self:canSubLogic()
      end
    end
  end
end

local function solutionWeapons(sname)
  local solutionlist = {
    ["#nioh_shield_skill"] = "qinggang_sword,spear",
    ["#vine_skill"] = "qinggang_sword,fan",
    ["#ex_vine_skill"] = "qinggang_sword,fan",
    ["#ex_nioh_shield_skill"] = "qinggang_sword,spear",
  }
  return solutionlist[sname]
end
--使用卡牌是否对目标有效
function Player:isCardEffectTo(target,card)
  if target.NoIdea then
    local max_v = target:NoIdea(self,card)
    if max_v == 999 then return false end
  end
  for _,s in ipairs(target.player_skills) do
    if s:isInstanceOf(TriggerSkill) and table.contains(s.events,fk.PreCardEffect) then
      local data = {
        from = self.id,
        to = target.id,
        card = card,
        nullifiedTargets = {},
        tos = {{target.id}},
        extra_data = {[s.trueName] = target.id}
      }
      if s:triggerable(fk.PreCardEffect, target, target, data) then
        if target:getMark("@@zhichi-turn") ~= 0 then 
          return (card.trueName == "slash" or card:isCommonTrick()) and false or true
        end
        if card.trueName == "slash" then
          local soluret = solutionWeapons(s.trueName)
          if soluret then
            if self.ignorearrmor then return true end
            local weapon = self:getEquipment(Card.SubtypeWeapon)
            if weapon then
              weapon = Fk:getCardById(weapon)
              if string.find(soluret,weapon.trueName) then return true end
            end
            return false,soluret
          end
        end
        return false
      end
    end
  end
  return true
end
--- 玩家根据响应和匹配方式。手中是否有对应牌。
function Player:getCardOrSkillByPat(pattern,area,playway,onlytype)
  local exp = Exppattern:Parse(pattern)
  if not onlytype or onlytype == 1 then
    local cards = type(area) == "number" and self.player_cards[area] or self:getCardIds(area)
    local haspatcard 
    for _,cid in ipairs(cards) do
      local card = Fk:getCardById(cid)
      if exp:match(card) and not self[playway](self,card) then haspatcard = card end
    end
    if haspatcard or (onlytype and onlytype == 1) then return haspatcard end
  end
  if not onlytype or onlytype == 2 then
    local express = playway == "prohibitResponse" and "enabledAtResponse" or "enabledAtPlay"
    local haspatskill = table.find(self.player_skills,function(s)
      if s:isInstanceOf(ViewAsSkill) and type(s.pattern) == "string" then
        local patret = exp:matchExp(s.pattern)
        return patret and s[express] and s[express](s,self)
      end
    end)
    return haspatskill
  end
end

--- 确认玩家判定区是否存在延迟锦囊牌。
function Player:hasDelayTrueTrick(card_name)
  for _, id in ipairs(self:getCardIds(Player.Judge)) do
    local c = self:getVirualEquip(id)
    if not c then c = Fk:getCardById(id) end
    if c.trueName == card_name then
      return true
    end
  end
end
-------------------------------修改或新增Player类一些函数来适配人机------------------

-------------------------------给人机添加卡牌优先级属性，值越大出牌阶段越优先使用----------------------
local usePrioCards = {
  {slash=17,thunder__slash=18,fire__slash=19,peach=14,analeptic=0,wdtx__slash=17.1,wdtx_thunder__slash=18.1,wdtx_fire__slash=19.1,wdtx__peach=14.1,},

  {lightning=1,god_salvation=15,amazing_grace=16,supply_shortage=16,indulgence=16,duel=22.5,savage_assault=23,archery_attack=23,collateral=23,
  iron_chain=25,fire_attack=26,snatch=29,ex_nihilo=27,ljsy=28,dismantlement=30,wdtx__dismantlement=30.1,wdtx__snatch=29.1,wdtx__duel=22.6,
  wdtx__ex_nihilo=27.1,wdtx__savage_assault=23.1,wdtx__archery_attack=23.1,wdtx_lightning=26.9,wdtx__indulgence=22.1,wdtx__iron_chain=25.1,
  wdtx__fire_attack=26.1,wdtx__supply_shortage=22.1,
  },

  {axe=0.5,red_spear=0.49,quenched_blade=0.51,poisonous_dagger=0.52,water_sword=0.52,thunder_blade=0.5,sw_feijiang=0.4,xyd_xueyingdao=0.4,
  blade=0.313,spear=0.313,kylin_bow=0.315,ice_sword=0.312,double_swords=0.312,guding_blade=0.312,halberd=0.314,
  crossbow = 0.311,rep_crossbow = 0.312,fan= 0.315,qinggang_sword = 0.312,wdtx__crossbow = 0.3,wdtx__axe = 0.51,wdtx__guding_blade=0.314,
  wdtx__fan = 0.316,wdtx__qinggang_sword=0.313,--武器
  vine = 0.23,nioh_shield=0.21,eight_diagram=0.25,--防具
  }
}
local useSpecialWeapon = {crossbow=5,rep_crossbow=4,fan=2,qinggang_sword=3}
function Fk:getAllCardIds(except)
  local result = {}
  for _, card in ipairs(self.cards) do
    if not (except and table.contains(except, card.id)) then
      if not table.contains(self:currentRoom().disabled_packs, card.package.name) then
        if not card.prio then
          card.prio = usePrioCards[card.type][card.name] or 0
          if card.type == Card.TypeEquip then
            card.prio = card.prio + 21
            if card.sub_type == Card.SubtypeWeapon and useSpecialWeapon[card.trueName] then 
              card.prio = card.prio - 6
              card.spe_weaponprio = useSpecialWeapon[card.trueName] 
            end --功能型装备需要面对有防具敌人思考使用
          end
        end
        table.insert(result, card.id)
      end
    end
  end
  return result
end
-------------------------------给人机添加卡牌优先级属性，值越大出牌阶段越优先使用----------------------

-------------------------------给技能添加卖血，不针对目标，顶装备（默认不顶）等让人机在一些复杂情景做出合理判断----------------------------------------
--卖血技能列表
local subhp__skills = {
  rangjie=1,jieming=1,kangli=1,cangxin=1,jiedao=1,chengxiang=1,yiji=1,longhun=1,jianxiong=1,quanji=1,qianlong=1,chouce=1,qingxian=1,xieshu=1,
  tianxiang=1,--可以一直受到伤害换收益直到低体力
  jinjian = 2,jishan=2,shibei=2,fangdu=2,baobian=2,quesong=2,difei = 2,huituo = 2,xingshen = 2,--每回合只能卖血一次
  liejie = 3,enyuan=3,fankui=3,ganglie=3--可以一直受到伤害换收益直到低体力（识别伤害来源是否为队友）
}
--最不想用牌针对的技能目标(值越高，攻击意愿越低)
local function NoIdeaByJueYong(player)
  return #player:getPile("jueyong_desperation") < player.hp and 3 or 0
end
local function NoIdeaByKongcheng(player)
  return #player.player_cards[Player.Hand] ~= 0 and 1 or 0
end
local function NoIdeaByLiuLi(player)
  return #player.player_cards[Player.Hand] + #player.player_cards[Player.Equip]  ~= 0 and 1.5 or 0
end
local function NoIdeaByWeiJing(player)
  return player:usedSkillTimes("weijing", Player.HistoryRound) == 0 and 1 or 0
end
local function NoIdeaByXiangLe(player,from,card)
  if not card or card.trueName ~= "slash" then return 0 end
  return #table.filter(from.player_cards[Player.Hand],function(cid) return Fk:getCardById(cid).type == Card.TypeBasic end) > 1 and 0 or 999
end
local function NoIdeaByJiBing(player)
  return #player:getPile("$mayuanyi_bing") > 0 and 1 or 0
end
local function NoIdeaByRenshi(player)
  return player.hp ~= player.maxHp and 1.5 and 0
end
local noidea__skills = {
  longdan = NoIdeaByKongcheng,jueyong = NoIdeaByJueYong,liuli = NoIdeaByLiuLi,tianxiang = NoIdeaByKongcheng,
  weijing = NoIdeaByWeiJing,xiangle = NoIdeaByXiangLe,
  jibing = NoIdeaByJiBing,yizan = NoIdeaByKongcheng,mingzhe = NoIdeaByKongcheng,renshi = NoIdeaByRenshi,
  pinghe = NoIdeaByKongcheng,qingguo=NoIdeaByKongcheng,
}
--顶掉装备收益
local repequip__skills = {zhimin=1,jingce=1,yizhao=1,fenyin=1,jianying=1,xiaoji=1,xuanfeng=1,qinguo=1,lianying=1,xiuwen=1}
--使用闪电的武将技能
local uselighting__skills = {guidao=true,guicai=true}
--有卖血属性但对方有下列技能用牌则不用卖血（值为expattern匹配对方使用牌来决定是否不卖血）
local nosubhp__skills = {["#ice_sword_skill"]="slash",zhiman="slash",jueqing="."}
--杀指向目标可以忽略防具或者有防具也能有收益
local ignorearrmor__skills = {["#poisonous_dagger_skill"]=true,jianchu=true,pojun=true,juelie=true,l_tuxi=true,xianzhen=true,}
--改变某些牌名优先级
local changecardprio__skills = {zhiheng={indulgence=22,supply_shortage=23.9,peach=20},tieji={slash=26.9},tieqi={slash=26.9},jianchu={slash=26.9},}
-------------------------------给技能添加卖血，不针对目标，顶装备（默认不顶）等让人机在一些复杂情景做出合理判断----------------------------------------

-------------------------------人机在出牌阶段使用某些牌前、或之后可以使用主动或转化技能-------------------------------------
local useactbefore__skills = {duanliang=16.9,--使用杀之后使用技能
fenxun=20,qixi=20,qiangwu=31,xueji=20,qimou=20,juguan=20,zhiheng=20,shizhan = 20,kurou=20,mingce=20,cuirui=20,tiaoxin=20,longdan=20,yanyu=20,--使用杀之前用技能
fenyue=21.9,fanjian=21.9,--使用乐之后用技能
shameng=26.9,ganlu=26.9,sanyao=26.9,poxi=26.9,yanzhu=26.9,guose=26.9,l_zhenfan=26.9,yijue=26.9,--使用拆顺无中等非伤害手牌后用技能
zunwei=31,yuanyu=31,cuijian=31,zhongjian=31,wencan=31,songci=31,jijie=31,anguo=31,yangwei=31,xunji=31,jixi=31,jixu=31,anxu=31--出牌阶段开始时用技能
} 
-------------------------------人机在出牌阶段使用某些牌前、或之后可以使用主动或转化技能-------------------------------------

-------------------------------人机核心全局技能：人机在出牌阶段，或者获得、失去技能时，刷新卖血，等信息---------------------------------------
local regisAttribute = function(player,event,attr,attrlist,data)
  if not attrlist[data.trueName] then return end
  if event == fk.EventAcquireSkill then 
    local value = attrlist[data.trueName]
    player[attr] = value
  else
    player[attr] = nil
  end
end
local aiInitSkills = fk.CreateTriggerSkill{
  name = "#ai_initskills",
  global = true,
  mute = true,
  priority = 1000,
  frequency = Skill.Compulsory,
  refresh_events = {fk.EventAcquireSkill,fk.EventLoseSkill,fk.DamageInflicted,fk.EventPhaseStart},
  can_refresh = function(self, event, target, player, data)
    if target ~= player or (event == fk.EventPhaseStart and player.phase ~= Player.Play) then return end
    -- p(event)
    -- p(player and player.general)
    -- p(target and target.general)
    -- dbg()
    if event == fk.DamageInflicted then
      if player.id < 0 and player.subhp and player.subhp == 2 and player:getMark("isdamaged-turn") == 0 then
        player.room:setPlayerMark(player,"isdamaged-turn",1)
      end
      return
    elseif event == fk.EventPhaseStart then
      if player.id < 0 then
        for _,s in ipairs(player.player_skills) do
          if s:isInstanceOf(ActiveSkill) or s:isInstanceOf(ViewAsSkill) then
            s.prio = useactbefore__skills[s.trueName] or 0
          end
        end
        player.responjinknum = 0
        player.responslashnum = 0
        player.useslashnum = 1
      end
      return
    end
    if data and data.global then return end
    -- p(data.name)
    -- dbg()
    regisAttribute(player,event,"NoIdea",noidea__skills,data)
    regisAttribute(player,event,"uselighting",uselighting__skills,data)
    regisAttribute(player,event,"subhp",subhp__skills,data)
    regisAttribute(player,event,"repequip",repequip__skills,data)
    regisAttribute(player,event,"ignorearrmor",ignorearrmor__skills,data)
    regisAttribute(player,event,"nosubhp",nosubhp__skills,data)
    regisAttribute(player,event,"changecardprio",changecardprio__skills,data)
  end,
  on_refresh = function(self, event, target, player, data)
    -- local room = player.room
  end,
}
Fk:addSkill(aiInitSkills)
-------------------------------人机核心全局技能：在出牌阶段，或者获得、失去技能时，刷新卖血，等信息---------------------------------------

-------------------------------修改room类让人机获得一些函数重要数据，或者修改、新增函数里面的代码---------------------------------------
local Room = require "server.room"
-- 修改构造武将牌堆，让非此扩展的其他模式的人机和玩家选特定将池，避免一些未优化弱智人机。
function Room:makeGeneralPile() 
  local aiconfig = HobbyGenPool:getgenPool("NOR_XLKJ","AIs")
  local playerconfig = HobbyGenPool:getgenPool("NOR_XLKJ","Players")

  local genspile = {}
  table.insertTable(genspile,aiconfig)
  table.insertTable(genspile,playerconfig)
  local aigenpool = table.clone(aiconfig)
  table.shuffle(aigenpool)
  self.general_pile = aigenpool
  --旧的将池
  local trueNames = {}
  local ret = {}
  -- if self.game_started then
    for _, player in ipairs(self.players) do
      trueNames[Fk.generals[player.general].trueName] = true
    end
  -- end
  for name, general in pairs(genspile) do
    if not trueNames[general] then
      table.insert(ret, general)
      trueNames[general] = true
    end
  end
  table.shuffle(ret)
  self.oldgeneral_pile = ret
  return true
end
--游戏开始前除了本房间模式，还需要加入人机核心全局技能
function Room:run()
  self.start_time = os.time()
  for _, p in fk.qlist(self.room:getPlayers()) do
    local player = ServerPlayer:new(p)
    player.room = self
    table.insert(self.players, player)
  end

  local mode = Fk.game_modes[self.settings.gameMode]
  local logic = (mode.logic and mode.logic() or GameLogic):new(self)
  self.logic = logic
  if mode.rule then 
    logic:addTriggerSkill(mode.rule) 
    logic:addTriggerSkill(aiInitSkills) 
  end
  logic:start()
end

fk.HandleAskForPlayCard = 97
fk.AfterAskForCardUse = 98
fk.AfterAskForCardResponse = 99
fk.AfterAskForNullification = 100
--- 询问玩家使用一张牌。在doRuest传数据时候人机可以接受到effectData里面谁在使用牌，指向谁。给人机函数AskForUseCard更好得到重要数据
---@param player ServerPlayer @ 要询问的玩家
---@param card_name? string @ 使用牌的牌名，若pattern指定了则可随意写，它影响的是烧条的提示信息
---@param pattern? string @ 使用牌的规则，默认就是card_name的值
---@param prompt? string @ 提示信息
---@param cancelable? boolean @ 能否点取消
---@param extra_data? UseExtraData @ 额外信息
---@param event_data? CardEffectEvent @ 事件信息
---@return CardUseStruct? @ 返回关于本次使用牌的数据，以便后续处理
function Room:askForUseCard(player, card_name, pattern, prompt, cancelable, extra_data, event_data)
  pattern = pattern or card_name
  if event_data and (event_data.disresponsive or table.contains(event_data.disresponsiveList or Util.DummyTable, player.id)) then
    return nil
  end

  if event_data and event_data.prohibitedCardNames then
    local exp = Exppattern:Parse(pattern)
    for _, matcher in ipairs(exp.matchers) do
      matcher.name = table.filter(matcher.name, function(name)
        return not table.contains(event_data.prohibitedCardNames, name)
      end)
      if #matcher.name == 0 then return nil end
    end
    pattern = tostring(exp)
  end

  local command = "AskForUseCard"
  self:notifyMoveFocus(player, card_name)
  cancelable = (cancelable == nil) and true or cancelable
  extra_data = extra_data or Util.DummyTable
  prompt = prompt or ""

  local askForUseCardData = {
    user = player,
    cardName = card_name,
    pattern = pattern,
    extraData = extra_data,
    eventData = event_data,
  }
  self.logic:trigger(fk.AskForCardUse, player, askForUseCardData)

  local useResult
  if askForUseCardData.result and type(askForUseCardData.result) == 'table' then
    useResult = askForUseCardData.result
  else
    local disabledSkillNames = {}

    repeat
      useResult = nil
      local othereventda
      if event_data and askForUseCardData and askForUseCardData.eventData then
        local eventda = askForUseCardData.eventData
        othereventda = {
          from = eventda.from,
          to = eventda.to,
          card = eventda.card and (eventda.card.id ~= 0 and eventda.card.id or {eventda.card.name,eventda.card.suit,eventda.card.number}),
          fixedResponseTimes = eventda.fixedResponseTimes
        }
      end
      -- p("==================AskForUseCard====================")
      -- pt(othereventda)
      -- dbg()
      local data = {card_name, pattern, prompt, cancelable, extra_data, disabledSkillNames,othereventda}

      Fk.currentResponsePattern = pattern
      self.logic:trigger(fk.HandleAskForPlayCard, nil, askForUseCardData, true)
      local result = self:doRequest(player, command, json.encode(data))
      askForUseCardData.afterRequest = true
      self.logic:trigger(fk.HandleAskForPlayCard, nil, askForUseCardData, true)
      Fk.currentResponsePattern = nil

      if result ~= "" then
        useResult = self:handleUseCardReply(player, result)

        if type(useResult) == "string" and useResult ~= "" then
          table.insertIfNeed(disabledSkillNames, useResult)
        end
      end
    until type(useResult) ~= "string"

    askForUseCardData.result = useResult
  end

  self.logic:trigger(fk.AfterAskForCardUse, player, askForUseCardData)
  return useResult
end
--- 询问一名玩家打出一张牌。在doRuest传数据时候人机可以接受到effectData里面谁在使用牌，指向谁。给人机函数AskForResponseCard更好得到重要数据
---@param player ServerPlayer @ 要询问的玩家
---@param card_name string @ 牌名
---@param pattern? string @ 牌的规则
---@param prompt? string @ 提示信息
---@param cancelable? boolean @ 能否取消
---@param extra_data? any @ 额外数据
---@param effectData? CardEffectEvent @ 关联的卡牌生效流程
---@return Card? @ 打出的牌
function Room:askForResponse(player, card_name, pattern, prompt, cancelable, extra_data, effectData)
  if effectData and (effectData.disresponsive or table.contains(effectData.disresponsiveList or Util.DummyTable, player.id)) then
    return nil
  end

  local command = "AskForResponseCard"
  self:notifyMoveFocus(player, card_name)
  cancelable = (cancelable == nil) and true or cancelable
  extra_data = extra_data or Util.DummyTable
  pattern = pattern or card_name
  prompt = prompt or ""

  local eventData = {
    user = player,
    cardName = card_name,
    pattern = pattern,
    extraData = extra_data,
    eventData = effectData,
  }
  self.logic:trigger(fk.AskForCardResponse, player, eventData)

  local responseResult
  if eventData.result then
    responseResult = eventData.result
  else
    local disabledSkillNames = {}

    repeat
      responseResult = nil
      local othereventda
      if eventData and eventData.eventData then
        local eventda = eventData.eventData
        othereventda = {
          from = eventda.from,
          to = eventda.to,
          card = eventda.card and (eventda.card.id ~= 0 and eventda.card.id or {eventda.card.name,eventda.card.suit,eventda.card.number}),
          fixedResponseTimes = eventda.fixedResponseTimes
        }
      end
      -- p("==================AskForResponseCard====================")
      -- pt(othereventda)
      -- dbg()
      local data = {card_name, pattern, prompt, cancelable, extra_data, disabledSkillNames,othereventda}

      Fk.currentResponsePattern = pattern
      eventData.isResponse = true
      self.logic:trigger(fk.HandleAskForPlayCard, nil, eventData, true)
      local result = self:doRequest(player, command, json.encode(data))
      eventData.afterRequest = true
      self.logic:trigger(fk.HandleAskForPlayCard, nil, eventData, true)
      Fk.currentResponsePattern = nil

      if result ~= "" then
        responseResult = self:handleUseCardReply(player, result)

        if type(responseResult) == "string" and responseResult ~= "" then
          table.insertIfNeed(disabledSkillNames, responseResult)
        end
      end
    until type(responseResult) ~= "string"

    if responseResult then
      responseResult = responseResult.card
    end

    eventData.result = responseResult
  end

  self.logic:trigger(fk.AfterAskForCardResponse, player, eventData)
  return responseResult
end
--- 同时询问多名玩家是否使用某一张牌。在doRuest传数据时候人机可以接受到effectData里面谁在使用牌，指向谁。给人机函数AskForUseCard更好得到重要数据
---
--- 函数名字虽然是“询问无懈可击”，不过其实也可以给别的牌用就是了。
---@param players ServerPlayer[] @ 要询问的玩家列表
---@param card_name string @ 询问的牌名，默认为无懈
---@param pattern string @ 牌的规则
---@param prompt? string @ 提示信息
---@param cancelable? boolean @ 能否点取消
---@param extra_data? any @ 额外信息
---@param effectData? CardEffectEvent @ 关联的卡牌生效流程
---@return CardUseStruct? @ 最终决胜出的卡牌使用信息
function Room:askForNullification(players, card_name, pattern, prompt, cancelable, extra_data, effectData)
  if #players == 0 then
    self.logic:trigger(fk.AfterAskForNullification, nil, { eventData = effectData })
    return nil
  end

  local command = "AskForUseCard"
  card_name = card_name or "nullification"
  cancelable = (cancelable == nil) and true or cancelable
  extra_data = extra_data or Util.DummyTable
  prompt = prompt or ""
  pattern = pattern or card_name

  local useResult
  local disabledSkillNames = {}

  repeat
    useResult = nil
    self:notifyMoveFocus(self.alive_players, card_name)
    self:doBroadcastNotify("WaitForNullification", "")

    local othereventda = {
      from = effectData.from,
      to = effectData.to,
      card = effectData.card and (effectData.card.id ~= 0 and effectData.card.id or {effectData.card.name,effectData.card.suit,effectData.card.number}),
    }
    local data = {card_name, pattern, prompt, cancelable, extra_data, disabledSkillNames,othereventda}

    Fk.currentResponsePattern = pattern

    local eventData = {
      cardName = card_name,
      pattern = pattern,
      extraData = extra_data,
      eventData = effectData,
    }
    -- p("==================askForNullification====================")
    -- pt(othereventda)
    -- dbg()
    self.logic:trigger(fk.HandleAskForPlayCard, nil, eventData, true)
    local winner = self:doRaceRequest(command, players, json.encode(data))
    eventData.afterRequest = true
    self.logic:trigger(fk.HandleAskForPlayCard, nil, eventData, true)

    if winner then
      local result = winner.client_reply
      useResult = self:handleUseCardReply(winner, result)

      if type(useResult) == "string" and useResult ~= "" then
        table.insertIfNeed(disabledSkillNames, useResult)
      end
    end
    Fk.currentResponsePattern = nil
  until type(useResult) ~= "string"

  local askForNullificationData = {
    result = useResult,
    eventData = effectData,
  }
  self.logic:trigger(fk.AfterAskForNullification, nil, askForNullificationData)
  return useResult
end
--修改no_trigger判断，默认用装备不trigger的逻辑，但是例如寒冰剑技能是需要trigger让人机核心全局技能识别到
function Room:handleAddLoseSkills(player, skill_names, source_skill, sendlog, no_trigger)
  if type(skill_names) == "string" then
    skill_names = skill_names:split("|")
  end

  if sendlog == nil then sendlog = true end

  if #skill_names == 0 then return end
  local losts = {}  ---@type boolean[]
  local triggers = {} ---@type Skill[]
  local lost_piles = {} ---@type integer[]
  for _, skill in ipairs(skill_names) do
    if string.sub(skill, 1, 1) == "-" then
      local actual_skill = string.sub(skill, 2, #skill)
      if player:hasSkill(actual_skill, true, true) then
        local lost_skills = player:loseSkill(actual_skill, source_skill)
        for _, s in ipairs(lost_skills) do
          self:doBroadcastNotify("LoseSkill", json.encode{
            player.id,
            s.name
          })

          if sendlog and s.visible then
            self:sendLog{
              type = "#LoseSkill",
              from = player.id,
              arg = s.name
            }
          end

          table.insert(losts, true)
          table.insert(triggers, s)
          if s.derived_piles then
            for _, pile_name in ipairs(s.derived_piles) do
              table.insertTableIfNeed(lost_piles, player:getPile(pile_name))
            end
          end
        end
      end
    else
      local sk = Fk.skills[skill]
      if sk and not player:hasSkill(sk, true, true) then
        local got_skills = player:addSkill(sk, source_skill)

        for _, s in ipairs(got_skills) do
          -- TODO: limit skill mark

          self:doBroadcastNotify("AddSkill", json.encode{
            player.id,
            s.name
          })

          if sendlog and s.visible then
            self:sendLog{
              type = "#AcquireSkill",
              from = player.id,
              arg = s.name
            }
          end

          table.insert(losts, false)
          table.insert(triggers, s)
        end
      end
    end
  end
  if no_trigger and (skill_names[1]== "#ice_sword_skill" or skill_names[1]== "-#ice_sword_skill") then
    -- p(skill_names)
    no_trigger = false
  end
  if (not no_trigger) and #triggers > 0 then
    for i = 1, #triggers do
      local event = losts[i] and fk.EventLoseSkill or fk.EventAcquireSkill
      self.logic:trigger(event, player, triggers[i])
    end
  end

  if #lost_piles > 0 then
    self:moveCards({
      ids = lost_piles,
      from = player.id,
      toArea = Card.DiscardPile,
      moveReason = fk.ReasonPutIntoDiscardPile,
    })
  end
end
-------------------------------修改room类让人机获得一些函数重要数据，或者修改、新增函数里面的代码---------------------------------------
